using Microsoft.Extensions.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Serilog;
using System.Diagnostics;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration;

/// <summary>
/// Microsoft.Extensions.Logging 和 Serilog 功能对比示例
/// </summary>
public static class LoggingComparison
{
    #region Microsoft.Extensions.Logging 示例

    /// <summary>
    /// 使用 Microsoft.Extensions.Logging 的典型日志记录
    /// </summary>
    /// <param name="logger">Microsoft日志记录器</param>
    public static void DemonstrateExtensionsLogging(Microsoft.Extensions.Logging.ILogger logger)
    {
        var userId = 12345;
        var userName = "张三";
        var processingTime = 150;

        // 基础日志记录
        logger.LogInformation("用户登录");
        
        // 带参数的日志记录
        logger.LogInformation("用户 {UserId} ({UserName}) 登录成功", userId, userName);
        
        // 结构化日志记录 - 语法相对简单
        logger.LogWarning("处理时间过长: {ProcessingTime}ms, 用户: {UserId}", processingTime, userId);
        
        // 异常日志记录
        try
        {
            throw new InvalidOperationException("测试异常");
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "处理用户 {UserId} 请求时发生错误", userId);
        }
        
        // 使用 LoggerMessage 进行高性能日志记录（编译时生成）
        LogMessages.UserLoggedIn(logger, userId, userName, null);
    }

    /// <summary>
    /// 高性能日志记录消息定义（编译时生成）
    /// </summary>
    private static class LogMessages
    {
        private static readonly Action<Microsoft.Extensions.Logging.ILogger, int, string, Exception?> _userLoggedIn =
            LoggerMessage.Define<int, string>(
                LogLevel.Information,
                new EventId(1001, "UserLogin"),
                "用户登录: UserId={UserId}, UserName={UserName}"
            );

        public static void UserLoggedIn(Microsoft.Extensions.Logging.ILogger logger, int userId, string userName, Exception? exception)
        {
            _userLoggedIn(logger, userId, userName, exception);
        }
    }

    #endregion

    #region Serilog 示例

    /// <summary>
    /// 使用 Serilog 的典型日志记录
    /// </summary>
    /// <param name="logger">Serilog日志记录器</param>
    public static void DemonstrateSerilog(Serilog.ILogger logger)
    {
        var userId = 12345;
        var userName = "张三";
        var processingTime = 150;
        
        // 基础日志记录
        logger.Information("用户登录");
        
        // 结构化日志记录 - 强大且直观
        logger.Information("用户 {UserId} ({UserName}) 登录成功", userId, userName);
        
        // 丰富的结构化日志功能
        logger
            .ForContext("RequestId", Guid.NewGuid())
            .ForContext("IPAddress", "192.168.1.100")
            .Warning("处理时间过长: {ProcessingTime}ms，用户: {@User}", 
                processingTime, new { Id = userId, Name = userName, Role = "Admin" });
        
        // 异常日志记录
        try
        {
            throw new InvalidOperationException("测试异常");
        }
        catch (Exception ex)
        {
            logger.Error(ex, "处理用户 {@User} 请求时发生错误", new { Id = userId, Name = userName });
        }
        
        // 条件日志记录
        logger
            .ForContext("Module", "Authentication")
            .Information("用户认证完成: {UserId}", userId);
            
        // 性能测量
        using (logger.BeginTimedOperation("数据库查询"))
        {
            // 模拟数据库查询
            System.Threading.Thread.Sleep(100);
        }
    }

    #endregion

    #region 配置对比

    /// <summary>
    /// Microsoft.Extensions.Logging 配置示例
    /// </summary>
    public static void ConfigureExtensionsLogging(IServiceCollection services, IConfiguration configuration)
    {
        services.AddLogging(builder =>
        {
            builder.ClearProviders(); // 清除默认提供程序
            builder.AddConfiguration(configuration.GetSection("Logging"));
            builder.AddConsole(); // 添加控制台日志
            // 注意：AddFile 需要安装 NuGet 包: Microsoft.Extensions.Logging.File 或类似包
            // builder.AddFile("logs/app.log"); // 需要第三方包
            // 仅在 Windows 平台下注册事件日志，避免 CA1416 跨平台告警
            if (OperatingSystem.IsWindows())
            {
                builder.AddEventLog(); // Windows事件日志
            }
            builder.AddDebug(); // 调试输出
            
            // 设置最小级别
            builder.SetMinimumLevel(LogLevel.Information);
        });
    }

    /// <summary>
    /// Serilog 配置示例
    /// </summary>
    public static Serilog.ILogger ConfigureSerilog()
    {
        return new LoggerConfiguration()
            .MinimumLevel.Information()
            .MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Warning)
            .MinimumLevel.Override("System", Serilog.Events.LogEventLevel.Warning)
            
            // 增强上下文信息
            .Enrich.FromLogContext()
            // 注意：以下扩展方法需要安装对应的 NuGet 包
            // .Enrich.WithMachineName()  // 需要: Serilog.Enrichers.Environment
            // .Enrich.WithThreadId()     // 需要: Serilog.Enrichers.Thread
            // .Enrich.WithProcessId()    // 需要: Serilog.Enrichers.Process
            .Enrich.WithProperty("Application", "JGSY.CMS.LowCode.Platform")
            
            // 多种输出目标
            .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} {NewLine}{Exception}")
            .WriteTo.File("logs/app-.log", 
                rollingInterval: RollingInterval.Day,
                retainedFileCountLimit: 7,
                outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
            
            // 条件写入
            .WriteTo.Logger(lc => lc
                .Filter.ByIncludingOnly(e => e.Level >= Serilog.Events.LogEventLevel.Error)
                .WriteTo.File("logs/errors-.log", rollingInterval: RollingInterval.Day))
                
            .CreateLogger();
    }

    #endregion

    #region 性能对比

    /// <summary>
    /// 性能测试对比
    /// </summary>
    public static void PerformanceComparison()
    {
        const int iterations = 100000;
        
        // Microsoft.Extensions.Logging 性能测试
        using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
        var msLogger = loggerFactory.CreateLogger("PerformanceTest");
        
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            msLogger.LogInformation("测试日志 {Index}", i);
        }
        stopwatch.Stop();
        var msTime = stopwatch.ElapsedMilliseconds;
        
        // Serilog 性能测试
        var serilogLogger = new LoggerConfiguration()
            .WriteTo.Console()
            .CreateLogger();
            
        stopwatch.Restart();
        for (int i = 0; i < iterations; i++)
        {
            serilogLogger.Information("测试日志 {Index}", i);
        }
        stopwatch.Stop();
        var serilogTime = stopwatch.ElapsedMilliseconds;
        
        Console.WriteLine($"Microsoft.Extensions.Logging: {msTime}ms");
        Console.WriteLine($"Serilog: {serilogTime}ms");
    }

    #endregion

    #region 特性对比总结

    /// <summary>
    /// 获取详细的特性对比
    /// </summary>
    public static Dictionary<string, object> GetFeatureComparison()
    {
        return new Dictionary<string, object>
        {
            ["Microsoft.Extensions.Logging"] = new
            {
                优点 = new[]
                {
                    "官方标准，与.NET生态系统深度集成",
                    "依赖注入原生支持",
                    "抽象层设计，可以轻松更换实现",
                    "LoggerMessage高性能编译时优化",
                    "简单易学，API直观"
                },
                缺点 = new[]
                {
                    "结构化日志支持相对简单",
                    "输出目标有限，需要第三方提供程序",
                    "配置选项相对有限",
                    "上下文信息支持不够丰富"
                },
                适用场景 = new[]
                {
                    "标准.NET应用程序",
                    "需要日志抽象的企业应用",
                    "团队偏好官方解决方案",
                    "简单的日志记录需求"
                }
            },
            
            ["Serilog"] = new
            {
                优点 = new[]
                {
                    "强大的结构化日志支持",
                    "丰富的Sinks（50+输出目标）",
                    "灵活的配置和过滤",
                    "优秀的性能",
                    "丰富的上下文信息支持",
                    "强大的查询和分析能力"
                },
                缺点 = new[]
                {
                    "学习曲线相对陡峭",
                    "配置可能变得复杂",
                    "第三方依赖",
                    "需要了解更多概念"
                },
                适用场景 = new[]
                {
                    "需要强大结构化日志的应用",
                    "微服务架构",
                    "需要复杂日志分析的系统",
                    "高性能应用",
                    "DevOps和监控重点的项目"
                }
            }
        };
    }

    #endregion
}

/// <summary>
/// Serilog扩展方法示例
/// </summary>
public static class SerilogExtensions
{
    /// <summary>
    /// 开始计时操作
    /// </summary>
    public static IDisposable BeginTimedOperation(this Serilog.ILogger logger, string operationName)
    {
        return new TimedOperation(logger, operationName);
    }
    
    private class TimedOperation : IDisposable
    {
        private readonly Serilog.ILogger _logger;
        private readonly string _operationName;
        private readonly Stopwatch _stopwatch;
        
        public TimedOperation(Serilog.ILogger logger, string operationName)
        {
            _logger = logger;
            _operationName = operationName;
            _stopwatch = Stopwatch.StartNew();
            _logger.Debug("开始操作: {OperationName}", operationName);
        }
        
        public void Dispose()
        {
            _stopwatch.Stop();
            _logger.Information("完成操作: {OperationName}，耗时: {ElapsedMs}ms", 
                _operationName, _stopwatch.ElapsedMilliseconds);
        }
    }
}
